//红与黑
#include <iostream>
#include <stdexcept>
#include <string>
#include <vector>
using namespace std;
static int arr[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
int res=0;
void dfs(vector<vector<char>>&map,vector<vector<bool>>&used,int curx,int cury)
{
    used[curx][cury]=true;
    res++;
    for(int i=0;i<4;i++)
    {
        int nx=curx+arr[i][0];
        int ny=cury+arr[i][1];
        if(nx<0 || nx>=map.size() || ny<0 || ny>=map[0].size()) continue;
        if(used[nx][ny] || map[nx][ny]!='.') continue;
        dfs(map,used,nx,ny);
    }
 
}
int main() 
{
    int m,n;
    while(cin>>m>>n)
    {
        vector<vector<char>>map(m,vector<char>(n));
        vector<vector<bool>>used(m,vector<bool>(n,false));
        int x=0,y=0;
        for(int i=0;i<m;i++)
        {
            for(int j=0;j<n;j++)
            {
                cin>>map[i][j];
                if(map[i][j]=='@') x=i,y=j;
            }
        }
        res=0;
        dfs(map,used,x,y);
        cout<<res<<endl;
    }
    return 0;
}
//复写零
class Solution {
public:
    void duplicateZeros(vector<int>& arr) 
    {
        int n=arr.size();
        int size=0;//个数
        int i;
        for(i=0;i<arr.size();i++) 
        {
            size+=arr[i]==0?2:1;
            if(size>=n) break;
        }
        //当前这个下标 
        //要么是0 且数组大小刚好为n 要么是0 且数组大小刚好为n+1
        //要么不是0 且数组大小刚好为n

        int cur=n-1;//记录现在开始填写arr数组的哪个下标
        if(size>n) 
        {
            arr[n-1]=0; //相当于现在只有一个空位啦 但我遇到了0
            cur--;
            i--;
        }
        while(cur>=0)
        {
            if(arr[i]) arr[cur--]=arr[i--];
            else
            {
                arr[cur--]=0;
                arr[cur--]=0;
                i--;
            }
        }
    }
};

//数青蛙
class Solution {
public:
    int minNumberOfFrogs(string croakOfFrogs) 
    {
        //思路： 用数组记录当前遍历结果中 各个字母的出现的次数

        //字符串中包含可能并发的青蛙叫，如果要判断当前的叫声是否合法
        //首先得知道 他是不是按照 croak的顺序来
        //所以我们可以采用一个count数组 计算已经遍历的元素中croak各个字符的出现次数
        //其次需要找到当前编译字符的前一个字符是否出现 如果没出现返回0即可
        //最后查看count数组中k字符的出现次数即可 有几个代表有几个青蛙的完整叫声
        //但是青蛙叫声可能是一只青蛙叫了多次 
        //所以在遍历到 c字母时 不能单纯 count[c]++ 而需要判断一下是不是已经有青蛙
        //完成了一次鸣叫 此时我们可以让他再叫一次
        string word="croak";
        int n=word.size();
        vector<int>count(n,0);
        unordered_map<char,int>hash;
        for(int i=0;i<word.size();i++) hash[word[i]]=i;

        for(auto ch:croakOfFrogs)
        {
            if(ch==word[0])
            {
                if(count[n-1]) count[n-1]--,count[0]++;
                else count[0]++;
            }
            else
            {
                int index=hash[ch];
                if(count[index-1]) count[index]++,count[index-1]--;
                else return -1;
            }
        }
        for(int i=0;i<n-1;i++)
        {
            if(count[i]!=0) return -1;
        }
        return count[n-1];
    }
};



//蘑菇矩阵
#include <iostream>
#include <vector>
using namespace std;
double func(vector<vector<int>>&map,int n,int m)
{
    vector<vector<double>>dp(n+1,vector<double>(m+1,0));
    dp[1][1]=1;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            if(i==1 && j==1) continue;
 
            if(map[i][j]==1) dp[i][j]=0;
            else
            {
                dp[i][j]=dp[i-1][j]*(j==m?1.0:0.5) + dp[i][j-1]*(i==n?1.0:0.5);
            }
        }
    }
    return dp[n][m];
}
 
int main() 
{
    int n,m,k;
    while(cin>>n>>m>>k)
    {
        vector<vector<int>>map(n+1,vector<int>(m+1,0));
        int x,y;
        while(k--)
        {
            cin>>x>>y;
            map[x][y]=1;
        }
        double res=func(map,n,m);
        printf("%.2f\n",res);
    }
    return 0;
}